package xfuzzy.alg_genetico.indeterminado.cross;

import java.util.List;
import java.util.Random;

import xfuzzy.alg_genetico.indeterminado.util.ArrayUtilities;
import xfuzzy.xfghl.codification.DoubleChromosome;
import xfuzzy.xfghl.model.XfghlConfig;

public abstract class Crossover {
	
	protected Random random;
	
	public Crossover(long seed)  {
		
		this.random = new Random(seed);
	}
	
	public void setRandom(Random random)  {
		
		this.random = random;
	}
	
	public Random getRandom()  {
		
		return this.random;
	}
	
	public abstract List<DoubleChromosome> cruzar(DoubleChromosome padre1, DoubleChromosome padre2, XfghlConfig config);
	
	protected DoubleChromosome cruzarVariables(DoubleChromosome padre1, DoubleChromosome padre2, DoubleChromosome hijo)  {
			
		int [] variables_c1 = padre1.getVariables();
		int [] variables_c2 = padre2.getVariables();
		int [] variables_hijo = new int[padre1.getNumVariables()];
		for (int i = 0; i < variables_hijo.length; i++)
			 variables_hijo[i] = -1;
		int indice1 = this.random.nextInt(padre1.getNumVariables());
		int indice2 = this.random.nextInt(padre1.getNumVariables());
		while (indice1 == indice2)
			indice2 = this.random.nextInt(padre1.getNumVariables());
		
		int indice_superior = 0, indice_inferior = 0;
		if (indice1 > indice2)  {
			indice_superior = indice1;
			indice_inferior = indice2;
		}
		else  {
			indice_superior = indice2;
			indice_inferior = indice1;
		}
		
		int indice_insercion = 0;
		for (int indice_cruce = indice_inferior; indice_cruce <= indice_superior; indice_cruce++)  {
				 variables_hijo[indice_cruce] = variables_c1[indice_cruce];
		}
		indice_insercion = (indice_superior + 1) % padre1.getNumVariables();
		
		int valor = -1;
		for (int indice_cruce = 0; indice_cruce < variables_c2.length; indice_cruce++)  {
			 valor = variables_c2[indice_cruce];
			 if (ArrayUtilities.pertenece(variables_hijo, valor) == false)  {
				 variables_hijo[indice_insercion] = valor;
				 indice_insercion = (indice_insercion + 1) % padre2.getNumVariables();
			 }
		}
		
		hijo.setVariables(variables_hijo);
		return hijo;
	}
}
